package app.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

/**
 * 该类主要用来解决异步时的数据返回问题
 * 
 * @author 周超 2018年3月1日 
 *
 */
@Slf4j
public class DataResponse {

	/**
     * 用Jackson重构。主要用于处理一些比较复杂的数据结构的返回，如LocalDate。简单的可以直接用@ResponseBody注解
	 *
	 * @author 杨健
	 * @since 2019-7-26
	 * @param response response响应
	 * @param obj 需要进行转换的数据
	 */
	public static void jsonResponse(HttpServletResponse response, Object obj){
		response.setContentType("application/json;charset=UTF-8");

		// 处理jdk1.8中的一些数据类型，如LocalDate
		ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new ParameterNamesModule())
                .registerModule(new Jdk8Module())
                .registerModule(new JavaTimeModule());

		try {
			String json = mapper.writeValueAsString(obj);
			PrintWriter writer = response.getWriter();
			writer.write(json);
			writer.flush();
		} catch (JsonProcessingException e) {
		    log.error(e.getMessage());
		} finally {
			return;
		}
	}
	/**
	 * 该方法用来进行指定文件的下载
	 * 
	 * @param response
	 * @param inputStream 对应文件的输入流
	 * @param fileName 返回下载时文件的名称（要带有扩展名）
	 */
	public static void StreamResponse(HttpServletResponse response,InputStream inputStream,String fileName){
		response.setContentType("application/octet-stream");
		response.addHeader("Content-Disposition","attachment;filename=" + fileName);
		try {
			ServletOutputStream outputStream = response.getOutputStream();
			int length = 0;
			byte[] buff=new byte[1024];
			while((length=inputStream.read(buff))>0){
				outputStream.write(buff, 0, length);
			}
			inputStream.close();
			outputStream.flush();
			outputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			return;
		}
	}

	/**
	 * 重构后的文件下载功能，利用SpringMVC的ResponseEntity
	 *
	 * @param inputStream 文件的输入流
	 * @param filename 响应给前台的文件名
	 * @return 返回ResponseEntity对象
	 * @throws IOException 读取输入流异常
	 */
	public static ResponseEntity<byte[]> fileResponse(InputStream inputStream, String filename) throws IOException {
		byte[] bytes = new byte[inputStream.available()];
		int read = inputStream.read(bytes);

		if (read == -1) {
			log.debug("文件输入流数据读入完成");
		}

		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		httpHeaders.setContentDispositionFormData("attachment", filename);

		return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);
	}
}
